home *** CD-ROM | disk | FTP | other *** search
- '****************************************************
- '* BITLIST.BAS - routines to manipulate bit lists *
- '****************************************************
-
- ' $INCLUDE: 'BITLIST.BI'
-
- CONST FALSE = 0, TRUE = NOT FALSE
-
- CONST CPI = 2 ' # chars in 1 integer
- CONST CS = 8 ' # bits in 1 character
-
- FUNCTION blCreate (Size%)
- '****************************************************
- '* blCreate - create a bitlist *
- '* *
- '* INP: Size - number of bits in the list *
- '* OUT: 'handle' of the new bitlist, NULL if *
- '* the bitlist could not be created. *
- '****************************************************
- SHARED MAllocSpace$, MasterPointers$, FirstFree%
- IF FirstFree% = 0 THEN
- ' this is the first allocation, no master pointers exist yet
- MasterPointers$ = STRING$(2, 0)
- FirstFree% = LEN(MasterPointers$) + 1
- NextList% = (FirstFree% - 1) \ 2
- mPtr% = FirstFree% - 2
- ELSE
- IF FirstFree% = LEN(MasterPointers$) + 1 THEN
- ' normal allocation, no master pointers have been freed
- MasterPointers$ = MasterPointers$ + STRING$(2, 0)
- FirstFree% = LEN(MasterPointers$) + 1
- NextList% = (FirstFree% - 1) \ 2
- mPtr% = FirstFree% - 2
- ELSE
- ' re-use a previously freed master pointer
- NextList% = (FirstFree% + 1) \ 2
- mPtr% = FirstFree%
- FirstFree% = ABS(CVI(MID$(MasterPointers$, mPtr%, 2)))
- END IF
- END IF
- lPtr% = LEN(MAllocSpace$) + 1
- MAllocSpace$ = MAllocSpace$ + STRING$(((Size%+CS-1)\CS+CPI),0)
- MID$(MAllocSpace$, lPtr%, 2) = MKI$(Size%)
- MID$(MasterPointers$, mPtr%, 2) = MKI$(lPtr%)
- blCreate = NextList%
- END FUNCTION
-
- SUB blDestroy (BitList%)
- '****************************************************
- '* blDestroy - destroy a bitlist *
- '* *
- '* INP: BitList% - 'handle' to bitlist to destroy *
- '****************************************************
- SHARED MAllocSpace$, MasterPointers$, FirstFree%
- ' de-reference the bitlist handle
- drBl% = CVI(MID$(MasterPointers$, BitList%*2-1, 2))
- ' Adjust the master pointers that come after the master pointer that
- ' points to the bitlist being destroyed.
- ' (if this was not the bitlist pointed to by the last master pointer
- ' in the master pointer list)
- IF BitList% * 2 < LEN(MasterPointers$) THEN
- Adjustment% = (CVI(MID$(MAllocSpace$, drBl%, 2)) + CS - 1) \ CS + CPI
- FOR aBl% = BitList% + 1 TO LEN(MasterPointers$) \ 2
- mPtr% = CVI(MID$(MasterPointers$, aBl% * 2 - 1, 2))
- IF mPtr% > 0 THEN
- ' (pointers with values less than 1 are in the free list)
- MID$(MasterPointers$, aBl% * 2 - 1, 2) = MKI$(mPtr% - Adjustment%)
- END IF
- NEXT aBl%
- END IF
- ' Do garbage collection on the master pointer list
- mPtr% = BitList% * 2 - 1
- MID$(MasterPointers$, mPtr%, 2) = MKI$(0)
- IF mPtr% + 1 = LEN(MasterPointers$) THEN
- ' this is the master pointer at the end of the list,
- ' so just get rid of it. We'll allocate it again if we need to.
- MasterPointers$ = LEFT$(MasterPointers$, mPtr% - 1)
- ELSE
- IF FirstFree% > LEN(MasterPointers$) THEN
- ' this is the first master pointer we've freed
- FirstFree% = mPtr%
- ELSE
- ' add this master pointer to the free list
- Prev% = 0: Done% = FALSE: WorkPtr% = FirstFree%
- DO UNTIL Done%
- ' look for the end of the list
- NextPtr% = ABS(CVI(MID$(MasterPointers$, WorkPtr%, 2)))
- IF NextPtr% = 0 THEN
- ' we've found the end of the free list
- ' set this node to pint to the master pointer we just freed
- MID$(MasterPointers$, WorkPtr%, 2) = MKI$(-mPtr%)
- Done% = TRUE
- ELSE
- ' follow the link
- WorkPtr% = NextPtr%
- END IF
- LOOP
- END IF
- END IF
- ' reclaim the space used by the list being destroyed
- listLen% = CVI(MID$(MAllocSpace$, drBl%, 2))
- SubStrLen% = (listLen% + CS - 1) \ CS + CPI
- Front$ = LEFT$(MAllocSpace$, drBl% - 1)
- RearStart% = drBl% + SubStrLen%
- Rear$ = MID$(MAllocSpace$, RearStart%, LEN(MAllocSpace$) - RearStart% + 1)
- MAllocSpace$ = Front$ + Rear$: Front$ = "": Rear$ = ""
- END SUB
-
- FUNCTION blGetBit (bl%, BitNum%)
- '****************************************************
- '* blGetBit - return current bit state *
- '* *
- '* INP: bl% - 'handle' to bitlist of interest *
- '* BitNum% - the bit number of interest *
- '* OUT: FALSE is bit is off or out of range, *
- '* TRUE otherwise. *
- '****************************************************
- SHARED MAllocSpace$, MasterPointers$, FirstFree%
- ' de-reference the bitlist handle
- drBl% = CVI(MID$(MasterPointers$, bl%*2-1, 2))
- IF BitNum% >= CVI(MID$(MAllocSpace$, drBl%, 2)) THEN
- fRes% = FALSE
- ELSE
- ByteNum% = BitNum% \ 8 + CPI
- fRes% = ASC(MID$(MAllocSpace$, drBl%+ByteNum%, 1)) AND 2 ^ (BitNum% MOD 8)
- END IF
- blGetBit = fRes%
- END FUNCTION
-
- FUNCTION blSetBit (bl%, BitNum%, State%)
- '****************************************************
- '* blSetBit - return current bit state *
- '* *
- '* INP: bl% - 'handle' to bitlist of interest *
- '* BitNum% - the bit number of interest *
- '* State% - the new bit state *
- '* OUT: TRUE on error, FALSE otherwise *
- '****************************************************
- SHARED MAllocSpace$, MasterPointers$, FirstFree%
- ' de-reference the bitlist handle
- drBl% = CVI(MID$(MasterPointers$, bl%*2-1, 2))
- IF BitNum% >= CVI(MID$(MAllocSpace$, drBl%, 2)) THEN
- fRes% = TRUE
- ELSE
- ByteNum% = BitNum% \ 8 + CPI
- Mask% = 2 ^ (BitNum% MOD 8)
- IF State% THEN
- MID$(MAllocSpace$, drBl%+ByteNum%, 1) = _
- CHR$(ASC(MID$(MAllocSpace$, drBl%+ByteNum%, 1)) OR Mask%)
- ELSE
- MID$(MAllocSpace$, drBl%+ByteNum%, 1) = _
- CHR$(ASC(MID$(MAllocSpace$, drBl%+ByteNum%, 1)) _
- AND ((NOT Mask%) AND &HFF))
- END IF
- fRes% = FALSE
- END IF
- blSetBit = fRes%
- END FUNCTION
-
- FUNCTION blListOp (Op%, bl1%, bl2%)
- '****************************************************
- '* blListOp - perform a list operation *
- '* *
- '* INP: Op% - operation code to perform: *
- '* blUNION, blINTERSECT, blCLEAR *
- '* blCOPY, blSET, blINVERT *
- '* bl1% - bitlist #1 *
- '* bl2% - bitlist #2 (or 0 if no 2nd bitlist *
- '* as for blCLEAR, blSET & blINVERT *
- '* *
- '* OUT: TRUE if UNION or INTERSECT or COPY detect *
- '* that the lists are different sizes, *
- '* FALSE otherwise. *
- '****************************************************
- SHARED MAllocSpace$, MasterPointers$, FirstFree%
- ' de-reference the bitlist handles
- drBl1% = CVI(MID$(MasterPointers$, bl1%*2-1, 2))
- IF bl2% <> 0 THEN
- drBl2% = CVI(MID$(MasterPointers$, bl2%*2-1, 2))
- END IF
- IF Op% = blUNION OR Op% = blINTERSECT OR Op% = blCOPY THEN
- IF CVI(MID$(MAllocSpace$, drBl1%, 2)) <> CVI(MID$(MAllocSpace$, drBl2%, 2)) _
- THEN
- fRes% = TRUE
- EXIT FUNCTION
- END IF
- END IF
-
- drBl1Len% = (CVI(MID$(MAllocSpace$, drBl1%, 2)) + CS-1)\CS
- fRes% = FALSE
- SELECT CASE Op%
- CASE blCLEAR
- MID$(MAllocSpace$, drBl1%+CPI, drBl1Len%) = STRING$(drBl1Len%, 0)
- CASE blSET
- MID$(MAllocSpace$, drBl1%+CPI, drBl1Len%) = STRING$(drBl1Len%, 255)
- CASE blINVERT
- FOR I%=CPI TO drBl1Len%+CPI-1
- MID$(MAllocSpace$, drBl1%+I%, 1) = _
- CHR$((NOT ASC(MID$(MAllocSpace$, drBl1%+I%, 1)) AND &HFF))
- NEXT I%
- CASE blUNION
- FOR I%=CPI TO drBl1Len%+CPI-1
- MID$(MAllocSpace$, drBl1%+I%, 1) = _
- CHR$(ASC(MID$(MAllocSpace$, drBl1%+I%, 1)) _
- OR ASC(MID$(MAllocSpace$, drBl2%+I%, 1)))
- NEXT I%
- CASE blINTERSECT
- FOR I%=CPI TO drBl1Len%+CPI-1
- MID$(MAllocSpace$, drBl1%+I%, 1) = _
- CHR$(ASC(MID$(MAllocSpace$, drBl1%+I%, 1)) _
- AND ASC(MID$(MAllocSpace$, drBl2%+I%, 1)))
- NEXT I%
- CASE blCOPY
- MID$(MAllocSpace$, drBl1%+CPI, drBl1Len%) = _
- MID$(MAllocSpace$, drBl2%+CPI, drBl1Len%)
- CASE ELSE
- fRes% = TRUE
- END SELECT
- blListOp = fRes%
- END FUNCTION
-
-